package br.mikhas.compiler.scanner;

import java.util.HashMap;
import java.util.Map;

public enum TokenType {

	IDENTIFIER(null),

	STRING_LITERAL(null),

	LPAREN("("),
	RPAREN(")"),
	LBRACK("["),
	RBRACK("]"),
	LBRACE("{"),
	RBRACE("}"),
	COLON(":"),
	SEMICOLON(";"),
	PERIOD("."),
	COMMA(","),
	CONDITIONAL("?"),

	/* Assignment operators. */
	ASSIGN("="),
	ASSIGN_BIT_OR("|="),
	ASSIGN_BIT_XOR("^="),
	ASSIGN_BIT_AND("&="),
	ASSIGN_SHL("<<="),
	ASSIGN_SAR(">>="),
	ASSIGN_ADD("+="),
	ASSIGN_SUB("-="),
	ASSIGN_MUL("*="),
	ASSIGN_DIV("/="),
	ASSIGN_MOD("%="),
	ASSIGN_TRUNC("~/="),

	/* Binary operators sorted by precedence. */
	OR("||"),
	AND("&&"),
	BIT_OR("|"),
	BIT_XOR("^"),
	BIT_AND("&"),
	SHL("<<"),
	SAR(">>"),
	ADD("+"),
	SUB("-"),
	MUL("*"),
	DIV("/"),
	TRUNC("~/"),
	MOD("%"),

	/* Compare operators sorted by precedence. */
	EQ("=="),
	NE("!="),
	EQ_STRICT("==="),
	NE_STRICT("!=="),
	LT("<"),
	GT(">"),
	LTE("<="),
	GTE(">="),

	/* Unary operators. */
	NOT("!"),
	BIT_NOT("~"),

	/* Count operators (also unary). */
	INC("++"),
	DEC("--"),

	/* [] operator overloading. */
	INDEX("[]");

	private final String text;
	private static final Map<String, TokenType> tokens;

	static {
		TokenType[] tokenTypes = values();
		tokens = new HashMap<String, TokenType>(tokenTypes.length);
		for (TokenType type : tokenTypes) {
			if (type.text != null)
				tokens.put(type.text, type);
		}
	}

	private TokenType(String text) {
		this.text = text;
	}

	public static TokenType lookup(String literal) {
		TokenType tokenType = tokens.get(literal);
		if (tokenType == null)
			tokenType = IDENTIFIER;
		return tokenType;
	}
}
